home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fatted Calf
/
The Fatted Calf.iso
/
Applications
/
Graphics
/
NXPlot3d
/
Source
/
PlotShape.m
< prev
next >
Wrap
Text File
|
1994-02-20
|
13KB
|
459 lines
#import "Plot3DView.h"
#import "PlotShape.h"
#import <ri/ri.h>
#import <math.h>
#define SC .05
#define SCP1 SC/1.732
#define SCP2 SC/.866
#define SCP3 SC/2.45
#define SCP4 SC/1.633-SCP3
#define SWAPP(a,b) { float f; int i; for (i=0; i<3; i++) { f=a[i]; a[i]=b[i]; b[i]=f; } }
/* used to position z axis label */
struct ZAXTAB { float x,y; int d; };
@implementation PlotShape:N3DShape
- renderSelf:(RtToken)context
{
int i,j,cm;
float x,y,z,xpm,ypm;
struct ZAXTAB zaxtab[8] = { {1.0,1.0,0},{-1.0,-1.0,1},{-1.0,1.0,1},{1.0,-1.0,0} ,{-1.0,-1.0,0},{1.0,1.0,1},{1.0,-1.0,1},{-1.0,1.0,0} };
static RtPoint square[4]= {{-1.0,-1.0,-1.01},{1.0,-1.0,-1.01},{1.0,1.0,-1.01},{-1.0,1.0,-1.01}};
static RtFloat squareST[8]= { 0.0,0.0,1.0,0.0,1.0,1.0,0.0,1.0 };
static RtPoint zsquare[4]= {{-1.0,-1.0,0},{1.0,-1.0,0},{1.0,1.0,0},{-1.0,1.0,0}};
static RtPoint sq1[4]= {{-1.0,-1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,1.0,1.0},{-1.0,-1.0,1.0}};
static RtPoint sq2[4]= {{-1.0,1.0,-1.0},{-1.0,1.0,1.0},{1.0,1.0,1.0},{1.0,1.0,-1.0}};
static RtPoint sq3[4]= {{1.0,1.0,1.0},{1.0,1.0,-1.0},{1.0,-1.0,-1.0},{1.0,-1.0,1.0}};
static RtPoint sq4[4]= {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,-1.0,1.0},{-1.0,-1.0,1.0}};
RtPoint scaX[4] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{-1.0,-1.0,-1.0} };
RtPoint scaY[4] = {{-1.0,-1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,-1.0} };
static RtPoint scaZ[4];
RtFloat scaST[8] = { 0,1.0,1.0,1.0,1.0,0.75,0,0.75 };
static RtFloat scaSTZ[8] = { 1.0,0.5,1.0,0,0,0,0,0.5 };
static RtPoint Box[8] = {{-SC,-SC,-SC},{-SC,-SC,SC},{-SC,SC,SC},{-SC,SC,-SC}, {SC,-SC,-SC},{SC,-SC,SC},{SC,SC,SC},{SC,SC,-SC}};
static RtInt BoxP[24] = {0,1,2,3,0,1,5,4,4,5,6,7,2,3,7,6,1,5,6,2,0,3,7,4};
static RtInt BoxV[6]={4,4,4,4,4,4};
static RtPoint Pyr[4] = {{0,-SCP2,-SCP4},{-SC,SCP1,-SCP4},{SC,SCP1,-SCP4}, {0,0,SCP4}};
static RtInt PyrP[12] = {0,1,2,0,1,3,0,2,3,1,2,3};
static RtInt PyrV[4] = {3,3,3,3};
static RtColor bgCol = {1.0,1.0,1.0};
static RtColor dCol = { 1.0,1.0,1.0 };
static RtColor opac = { .2,.2,.2 };
static RtPoint bsquare[4]= {{-100.0,-100.0,-40.0},{100.0,-100.0,-40.0},{100.0,100.0,-40.0},{-100.0,100.0,-40.0}};
RtFloat *SZ;
char tmaps[100],*tmap;
char home[60];
sprintf(home,"/tmp/%s",getenv("USER"));
if (getenv("USER")==NULL) strcpy(home,"/tmp");
sprintf(tmaps,"%s/plot3d.tx",home);
tmap=tmaps;
RiDeclare("texname","uniform string");
RiDeclare("Cst","uniform float");
RiDeclare("Csp","uniform float");
RiSurface("constant",RI_NULL);
if (mode>=4) {
RiTransformBegin();
RiRotate(chi,0,0,1.0);
RiRotate(-theta+90.0,1.0,0,0);
RiColor(bgCol);
RiPolygon(4,RI_P,(RtPointer)bsquare,RI_NULL);
RiTransformEnd();
}
RiSurface("matte",RI_NULL);
RiColor(flagcol[1]);
/* FLOOR */
if (flags&2) {
if (mode>=4 && Omode&OVER_base) {
/* RiTextureCoordinates(0,0,.5,0,0,.5,.5,.5);*/
RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_NULL);
}
RiPolygon(4,RI_P,(RtPointer)square,RI_ST,(RtPointer)squareST,RI_NULL);
}
RiSurface("matte",RI_NULL);
RiColor(dCol);
if (chi>90.0&&chi<270.0) ypm=-1.0;
else ypm=1.0;
if (chi<180.0) xpm=-1.0;
else xpm=1.0;
/* Backs */
if (flags&4) {
RiColor(flagcol[2]);
if (chi>90.0&&chi<270.0) RiPolygon(4,RI_P,(RtPointer)sq4,RI_NULL);
else RiPolygon(4,RI_P,(RtPointer)sq2,RI_NULL);
if (chi<180.0) RiPolygon(4,RI_P,(RtPointer)sq1,RI_NULL);
else RiPolygon(4,RI_P,(RtPointer)sq3,RI_NULL);
if (flags&8) {
RiColor(flagcol[3]);
RiTransformBegin();
RiTranslate(xpm,0.0,0.0);
RiRotate(90.0,1.0,0.0,0.0);
RiTranslate(0,tickmin[2],0.0);
for (z=tickmin[2]; z<1.0; z+=tickstp[2]) {
RiCylinder(.007,-1.0,1.0,360.0,RI_NULL);
RiTranslate(0,tickstp[2],0);
}
RiTransformEnd();
RiTransformBegin();
RiTranslate(0.0,ypm,0.0);
RiRotate(90.0,0.0,1.0,0.0);
RiTranslate(-tickmin[2],0,0);
for (z=tickmin[2]; z<1.0; z+=tickstp[2]) {
RiCylinder(.007,-1.0,1.0,360.0,RI_NULL);
RiTranslate(-tickstp[2],0,0);
}
RiTransformEnd();
}
}
/* Axes */
if (flags&1 && data[0].sym!=6) {
RiColor(flagcol[0]);
RiTransformBegin();
RiTranslate(-1.0,-1.0,-1.0);
RiCylinder(.015,0.0,2.0,360.0,RI_NULL);
RiTransformEnd();
RiTransformBegin();
RiRotate(-90.0,0,1.0,0.0);
RiTranslate(-1.0,-1.0,-1.0);
RiCylinder(.015,0.0,2.0,360.0,RI_NULL);
RiTransformEnd();
RiTransformBegin();
RiRotate(90.0,1.0,0.0,0.0);
RiTranslate(-1.0,-1.0,-1.0);
RiCylinder(.015,0.0,2.0,360.0,RI_NULL);
RiTransformEnd();
}
else if (flags&1) {
RiColor(flagcol[0]);
RiTransformBegin();
RiCylinder(.015,-1.0,1.0,360.0,RI_NULL);
RiTransformEnd();
RiTransformBegin();
RiRotate(-90.0,0,1.0,0.0);
RiCylinder(.015,-1.0,1.0,360.0,RI_NULL);
RiTransformEnd();
RiTransformBegin();
RiRotate(90.0,1.0,0.0,0.0);
RiCylinder(.015,-1.0,1.0,360.0,RI_NULL);
RiTransformEnd();
}
/*else if (flags&1) {
RiColor(flagcol[0]);
RiLine(2,RI_P,axes1,RI_NULL);
RiLine(2,RI_P,axes2,RI_NULL);
RiLine(2,RI_P,axes3,RI_NULL);
}*/
/* Ticks */
if (flags&8) {
RiColor(flagcol[0]);
RiTransformBegin();
RiRotate(-90.0,0,1.0,0.0);
RiTranslate(-1.0,-ypm,-1.0);
RiCylinder(.015,0.0,2.0,360.0,RI_NULL);
RiTransformEnd();
RiTransformBegin();
RiRotate(90.0,1.0,0.0,0.0);
RiTranslate(-xpm,-1.0,-1.0);
RiCylinder(.015,0.0,2.0,360.0,RI_NULL);
RiTransformEnd();
RiColor(flagcol[3]);
RiTransformBegin();
RiTranslate(0,-ypm,-1.0);
RiRotate(90,0,1.0,0);
for (x=tickmin[0]; x<1.0; x+=tickstp[0]) RiDisk(x,.03,360.0,RI_NULL);
RiTransformEnd();
RiTransformBegin();
RiTranslate(-xpm,0.0,-1.0);
RiRotate(90,1.0,0,0);
for (x=tickmin[1]; x<1.0; x+=tickstp[1]) RiDisk(x,.03,360.0,RI_NULL);
RiTransformEnd();
if (!(flags&4)) {
RiTranslate(-1.0,-1.0,0.0);
for (x=tickmin[2]; x<1.0; x+=tickstp[2])
RiDisk(x,.03,360.0,RI_NULL);
RiTranslate(1.0,1.0,0.0);
}
}
/* Labels */
if (flags&32 && mode>=4) {
if (ypm<0) { SWAPP(scaX[0],scaX[1]); SWAPP(scaX[2],scaX[3]); }
if (xpm>0) { SWAPP(scaY[0],scaY[1]); SWAPP(scaY[2],scaY[3]); }
scaX[0][1]=scaX[1][1]=scaX[2][1]=scaX[3][1]=-ypm;
scaY[0][0]=scaY[1][0]=scaY[2][0]=scaY[3][0]=-xpm;
scaX[0][2]-=.5/aspect;
scaX[1][2]-=.5/aspect;
scaY[0][2]-=.5/aspect;
scaY[1][2]-=.5/aspect;
i=floor(chi/45.0);
scaZ[0][2]=scaZ[1][2]=-1.0;
scaZ[2][2]=scaZ[3][2]=1.0;
scaZ[0][0]=scaZ[3][0]=zaxtab[i].x;
scaZ[1][0]=scaZ[2][0]=zaxtab[i].x;
scaZ[0][1]=scaZ[3][1]=zaxtab[i].y;
scaZ[1][1]=scaZ[2][1]=zaxtab[i].y;
if (i%2==0) {
scaZ[1][zaxtab[i].d]*=(1.0+aspect);
scaZ[2][zaxtab[i].d]*=(1.0+aspect);
}
else {
scaZ[0][zaxtab[i].d]*=(1.0+aspect);
scaZ[3][zaxtab[i].d]*=(1.0+aspect);
}
sprintf(tmaps,"%s/plot3dxyz.tx",home);
x=1.05/ambient; y=0.0;
RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_KA,(RtPointer)&x,RI_KD,(RtPointer)&y,RI_NULL);
RiPolygon(4,RI_P,(RtPointer)scaX,RI_ST,(RtPointer)scaST,RI_NULL);
scaST[1]=scaST[3]=.75;
scaST[5]=scaST[7]=.5;
RiPolygon(4,RI_P,(RtPointer)scaY,RI_ST,(RtPointer)scaST,RI_NULL);
RiPolygon(4,RI_P,(RtPointer)scaZ,RI_ST,(RtPointer)scaSTZ,RI_NULL);
sprintf(tmaps,"%s/plot3d.tx",home);
RiSurface("matte",RI_NULL);
}
/* Planes */
if (flags&16) {
RiColor(flagcol[4]);
RiOpacity(opac);
RiTransformBegin();
RiTranslate(0,0,tickmin[2]);
for (z=tickmin[2]; z<1.0; z+=tickstp[2]) {
RiPolygon(4,RI_P,(RtPointer)zsquare,RI_NULL);
RiTranslate(0,0,tickstp[2]);
}
RiTransformEnd();
RiOpacity(dCol);
}
if (data==NULL) return self;
for (i=0; i<MAXSETS; i++) {
if (data[i].sym<0) continue;
if ((mode&3)>=2) RiColor(data[i].mapcol[0]);
else RiColor(data[i].mapcol[0]);
cm=data[i].mapmode;
switch(data[i].sym) {
case 0:
for (j=0; j<data[i].ndata; j++) {
x=data[i].data[j].x;
y=data[i].data[j].y;
z=data[i].data[j].z;
if (cm) RiColor(data[i].color[j]);
RiTransformBegin();
RiTranslate(x,y,z);
RiPointsPolygons(6,BoxV,BoxP,RI_P,(RtPointer)Box,RI_NULL);
RiTransformEnd();
}
break;
case 1:
for (j=0; j<data[i].ndata; j++) {
x=data[i].data[j].x;
y=data[i].data[j].y;
z=data[i].data[j].z;
if (cm) RiColor(data[i].color[j]);
RiTransformBegin();
RiTranslate(x,y,z);
RiPointsPolygons(4,PyrV,PyrP,RI_P,(RtPointer)Pyr,RI_NULL);
RiTransformEnd();
}
break;
case 2:
for (j=0; j<data[i].ndata; j++) {
x=data[i].data[j].x;
y=data[i].data[j].y;
z=data[i].data[j].z;
if (cm) RiColor(data[i].color[j]);
RiTransformBegin();
RiTranslate(x,y,z);
RiSphere(SC,-SC,SC,360.0,RI_NULL);
RiTransformEnd();
}
break;
case 3:
for (j=0; j<data[i].ndata; j++) {
x=data[i].data[j].x;
y=data[i].data[j].y;
z=data[i].data[j].z;
if (cm) RiColor(data[i].color[j]);
RiTransformBegin();
RiTranslate(x,y,z);
RiTorus(SC,SC/3.0,0,360.0,360.0,RI_NULL);
RiTransformEnd();
}
break;
case 4:
for (j=0; j<data[i].ndata; j++) {
x=data[i].data[j].x;
y=data[i].data[j].y;
z=data[i].data[j].z;
if (cm) RiColor(data[i].color[j]);
RiTransformBegin();
RiTranslate(x,y,z);
RiCylinder(SC,-SC,SC,360.0,RI_NULL);
RiTransformEnd();
}
break;
case 5:
/* if (data[i].fileData!=NULL) break; /* no mesh in file mode */
if (data[i].nx*data[i].ny!=data[i].ndata) break;
if (mode>=4 && Omode&OVER_csurf) {
SZ=malloc(data[i].ndata*sizeof(RtFloat));
for (j=0; j<data[i].ndata; j++) SZ[j]=(data[i].data[j].z+1.0)/2.0;
RiSurface("contour",(RtToken)"Cst",(RtPointer)&Cst, (RtToken)"Csp",(RtPointer)&Csp,RI_NULL);
if (cm)
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,
RI_S,(RtPointer)SZ,RI_CS,(RtPointer)data[i].color,RI_NULL);
else
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,
RI_S,(RtPointer)SZ,RI_NULL);
free(SZ);
}
else if (mode>=4 && Omode&OVER_surf) {
RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_NULL);
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,RI_NULL);
}
else if (cm)
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,
data[i].ny,RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,RI_CS,
(RtPointer)data[i].color,RI_NULL);
else RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,RI_NULL);
break;
case 6:
if (data[i].nx*data[i].ny!=data[i].ndata) break;
if (mode>=4 && Omode&OVER_csurf) {
SZ=malloc(data[i].ndata*sizeof(RtFloat));
for (j=0; j<data[i].ndata; j++) SZ[j]=(data[i].data[j].z+1.0)/2.0;
RiSurface("contour",(RtToken)"Cst",(RtPointer)&Cst, (RtToken)"Csp",(RtPointer)&Csp,RI_NULL);
if (cm)
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,
RI_S,(RtPointer)SZ,RI_CS,(RtPointer)data[i].color,RI_NULL);
else
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,
RI_S,(RtPointer)SZ,RI_NULL);
free(SZ);
}
else if (mode>=4 && Omode&OVER_surf) {
RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_NULL);
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,RI_NULL);
}
else if (cm)
RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,
data[i].ny,RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,RI_CS,
(RtPointer)data[i].color,RI_NULL);
else RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny,
RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,RI_NULL);
break;
}
}
return self;
}
-setTicks:(RtPoint)Min :(RtPoint)Step
{
tickmin[0]=Min[0];
tickmin[1]=Min[1];
tickmin[2]=Min[2];
tickstp[0]=Step[0];
tickstp[1]=Step[1];
tickstp[2]=Step[2];
return self;
}
-setData:(SetPref *)Data :(int)Mode :(int)Flags
{
data=Data;
mode=Mode;
flags=Flags;
/*
mmx[0]=mmy[0]=mmz[0]=MAXFLOAT;
mmx[1]=mmy[1]=mmz[1]=-MAXFLOAT;
for (i=0; i<MAXSETS; i++) {
for (j=0; j<data[i].ndata; j++) {
if (data[i].data[j].x<mmx[0]) mmx[0]=data[i].data[j].x;
if (data[i].data[j].x>mmx[1]) mmx[1]=data[i].data[j].x;
if (data[i].data[j].y<mmy[0]) mmy[0]=data[i].data[j].y;
if (data[i].data[j].y>mmy[1]) mmy[1]=data[i].data[j].y;
if (data[i].data[j].z<mmz[0]) mmz[0]=data[i].data[j].z;
if (data[i].data[j].z>mmz[1]) mmz[1]=data[i].data[j].z;
}
}
mmx[1]=(mmx[1]-mmx[0])/2.0;
mmy[1]=(mmy[1]-mmy[0])/2.0;
mmz[1]=(mmz[1]-mmz[0])/2.0;
*/
return self;
}
-setFlagColors:(RtColor *)col
{
bcopy(col,flagcol,sizeof(RtColor)*5);
return self;
}
- setSurfaceType:(N3DSurfaceType)st andDescendants:(BOOL)flag
{
[super setSurfaceType:st andDescendants:flag];
return self;
}
-setAng:(float)alt :(float)az :(float)Aspect :(float)Ambient
{
RtPoint ax;
RtMatrix mx = { { -1.0,0,0,0 }, {0,1.0,0,0}, {0,0,1.0,0}, {0,0,0,1.0} };
theta=alt*180.0/M_PI;
chi=az*180.0/M_PI;
aspect=Aspect;
ambient=Ambient;
[self setTransformMatrix:mx];
[self scale:1.0 :1.0 :Aspect];
ax[0]=ax[1]=0; ax[2]=1.0;
[self rotateAngle:chi axis:ax];
ax[0]=1.0; ax[1]=ax[2]=0;
[self rotateAngle:theta-90.0 axis:ax];
return self;
}
- setOver:(int)OMODE
{
Omode=OMODE;
return self;
}
-setContour:(float)start :(float)space
{
Cst=start;
Csp=space;
return self;
}
@end